package top.infopub.util;


import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


/**
 * Date工具类</br>
 * 涉及到格式化等方法请使用Apache common DateUtils和 DateFormatUtils
 * @author Awoke
 * @version 2018-09-14
 * @see DateUtil
 * @since
 */
public final class DateUtil {

    /**
     * 日期格式 yyyy-MM-dd
     */
    public static final String DATE_STYLE_SIMPLE = "yyyy-MM-dd";

    /**
     * 日期格式 yyyy-MM
     */
    public static final String DATE_STYLE_YYYY_MM = "yyyy-MM";

    /**
     * 日期格式 yyyy年MM月dd日
     */
    public static final String DATE_STYLE_SIMPLE_CH = "yyyy年MM月dd日";

    /**
     * 日期格式yyyy年MM月dd日HH时mm分
     */
    public static final String DATE_STYLE_BASIC_CH = "yyyy年MM月dd日HH时mm分";

    /**
     * 日期格式yyyy年MM月dd日 HH:mm:ss
     */
    public static final String DATE_STYLE_WX = "yyyy年MM月dd日 HH:mm:ss";

    /**
     * 日期格式  MM-dd
     */
    public static final String DATE_STYLE_MM_DD = "MM.dd";

    /**
     * 日期格式  yyyy-MM-dd 00:00:00
     */
    public static final String DATE_STYLE_START = "yyyy-MM-dd 00:00:00";

    /**
     * 日期格式  yyyy-MM-dd 23:59:59
     */
    public static final String DATE_STYLE_END = "yyyy-MM-dd 23:59:59";

    /**
     * 日期格式 含时分秒
     */
    public static final String DATE_STYLE_BASIC = "yyyy-MM-dd HH:mm:ss";

    /**
     * 日期格式 含时分秒毫秒
     */
    public static final String DATE_STYLE_BASIC_SS = "yyyy-MM-dd HH:mm:ss.SSS";

    /**
     * 日期格式 含时分
     */
    public static final String DATE_STYLE_WITHOUT_SEC = "yyyy-MM-dd HH:mm";

    /**
     * 日期格式 MM月dd日 HH:00
     */
    public static final String DATE_CLAIM_TIME = "MM月dd日 HH:00";

    /**
     * log
     */
    private static final Logger log = LoggerFactory.getLogger(DateUtil.class);

    /**
     * 获得当前时间的yyyy-MM-dd HH:mm:ss格式
     * @return
     * @see
     */
    public static String currentDateDef() {
        return currentDate(DATE_STYLE_BASIC);
    }

    /**
     * 获得当前时间
     * @param style 格式
     * @return
     * @see
     */
    public static String currentDate(String style) {
        return DateFormatUtils.format(new java.util.Date(), style);
    }

    /**
     * 时间转成字符串
     * @param style 格式
     * @return
     * @see
     */
    public static String utilDate2String(java.util.Date date, String style) {
        return DateFormatUtils.format(date, style);
    }

    /**
     * 获得当前时间 前n天的日期
     * @param style 格式
     * @return
     * @see
     */
    public static String currentDateDaysAgo(String style, int daysAgo) {
        return DateFormatUtils.format(DateUtils.addDays(new java.util.Date(), -daysAgo), style);
    }

    /**
     * 获得当前时间 前n天的日期的long值 单位：毫秒
     * @return
     * @see
     */
    public static long currentDateDaysAgo(int daysAgo) {
        return DateUtils.addDays(new java.util.Date(), -daysAgo).getTime();
    }

    /**
     * 将字符串按指定格式转换成java.util.Date<br>
     * @param str String型日期
     * @param style 日期格式
     * @return 日期
     * @see
     */
    public static java.util.Date string2UtilDate(String str, String style) {
        try {
            java.util.Date utilDate = DateUtils.parseDate(str, new String[] {style});
            return utilDate;
        }
        catch (ParseException e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 将字符串按指定格式转换成java.sql.Date<br>
     * @param str String型日期
     * @param style 日期格式
     * @return 日期
     * @see
     */
    public static java.sql.Date string2SqlDate(String str, String style) {
        try {
            java.util.Date utilDate = DateUtils.parseDate(str, new String[] {style});
            return new java.sql.Date(utilDate.getTime());
        }
        catch (ParseException e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 判断日期是否是昨天
     * @param date
     * @return true=是 false=否
     * @see
     */
    public static boolean isYesterday(java.util.Date date) {
        java.util.Date yesterday = DateUtils.addDays(new java.util.Date(), -1);
        return isSameDay(date, yesterday);
    }

    /**
     * 判断日期是否是今天
     * @param date
     * @return true=是 false=否
     * @see
     */
    public static boolean isToday(java.util.Date date) {
        return isSameDay(date, new java.util.Date());
    }

    /**
     * 判断两个日期是否是同一天
     * @param date
     * @return true=是 false=否
     * @see
     */
    public static boolean isSameDay(java.util.Date date1, java.util.Date date2) {
        return DateUtils.isSameDay(date1, date2);
    }

    /**
     * 判断给定日期是否在当前日期之后
     * @param date
     * @return true=是 false=否
     * @see
     */
    public static boolean isAfterNow(java.util.Date when) {
        java.util.Date now = new java.util.Date();

        return now.before(when);
    }

    /**
     * end-start 相差的时间 满足 HH时mm分ss秒的格式
     * @return
     * @see
     */
    public static String timeDiff(java.util.Date start, java.util.Date end) {
        // 毫秒
        long diff = end.getTime() - start.getTime();
        long hour = diff / (60 * 60 * 1000);
        long mins = (diff / (60 * 1000)) - hour * 60;
        long secs = (diff / 1000) - hour * 60 * 60 - mins * 60;

        return hour + "时" + mins + "分" + secs + "秒";
    }

    /**
     * end-start 相差的时间 满足 HH:mm:ss的格式
     * @return
     * @see
     */
    public static String timeDiffColon(java.util.Date start, java.util.Date end) {
        // 毫秒
        long diff = end.getTime() - start.getTime();
        long hour = diff / (60 * 60 * 1000);
        long mins = (diff / (60 * 1000)) - hour * 60;
        long secs = (diff / 1000) - hour * 60 * 60 - mins * 60;

        return hour + ":" + mins + ":" + secs;
    }

    /**
     * end-start 相差的时间秒数
     * @return
     * @see
     */
    public static String timeDiffSeconds(java.util.Date start, java.util.Date end) {
        // 毫秒
        long diff = end.getTime() - start.getTime();
        return String.valueOf(diff / 1000);
    }

    /**
     * end-start 相差的时间分钟数
     * @return
     * @see
     */
    public static String timeDiffMins(java.util.Date start, java.util.Date end) {
        // 毫秒
        long diff = end.getTime() - start.getTime();
        return String.valueOf(diff / (1000 * 60) < 0 ? 0 : diff / (1000 * 60));
    }

    /**
     * end-start 相差的时间小时数
     * @return
     * @see
     */
    public static double timeDiffHours(java.util.Date start, java.util.Date end) {
        long diff = end.getTime() - start.getTime();
        return diff / (1000 * 60 * 60);
    }

    /**
     * end-start 相差的时间天数(小数)
     * @return
     * @see
     */
    public static double timeDiffDays(java.util.Date start, java.util.Date end) {
        return timeDiffHours(start, end) / 24;
    }

    /**
     * end-start 相差的时间天数(整数)
     * @return
     * @see
     */
    public static int timeDiffIntDays(java.util.Date start, java.util.Date end) {
        Double days = timeDiffHours(timeDayInitial(start), timeDayInitial(end)) / 24;
        return days.intValue();
    }

    /**
     * 获取某一天的初始时间 2018-11-11 11:11:01返回2018-11-11
     * @return
     * @see
     */
    public static java.util.Date timeDayInitial(java.util.Date time) {
        return string2UtilDate(utilDate2String(time, DATE_STYLE_SIMPLE), DATE_STYLE_SIMPLE);
    }

    /**
     * 获取当前月月初的第一天
     * @param style
     * @return
     * @see
     */
    public static String firstDayOfCurrentMonth(String style) {
        Calendar cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        return DateFormatUtils.format(cale, style);
    }

    /**
     * 日期格式字符串转换成时间戳
     * @param date_str 字符串日期
     * @param format 如：yyyy-MM-dd HH:mm:ss
     * @return
     */

    public static String date2TimeStamp(String date_str,String format){
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return String.valueOf(sdf.parse(date_str).getTime()/1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
    /**
     * 时间戳转换成日期格式字符串
     * @param ms 精确到毫秒的字符串
     * @param format
     * @return
     */
    public static String timeStamp2Date(String ms,String format) {
        if(ms == null || ms.isEmpty() || ms.equals("null")){
            return "";
        }
        if(format == null || format.isEmpty()){
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(ms)));
    }

    /**
     * Test
     * @param args
     * @see
     */
    public static void main(String[] args)
        throws Exception {
        //00:00:00 -- 23:59:59

        /*String date = "2014-11-05 21:59:59";
        java.util.Date dateSrc = DateUtils.parseDate(date, new String[] {DATE_STYLE_BASIC});
        System.out.println(isToday(dateSrc));

        String yestDay = "2014-11-02 01:00:00";
        java.util.Date yestDaySrc = DateUtils.parseDate(yestDay, new String[] {DATE_STYLE_BASIC});
        System.out.println(isYesterday(yestDaySrc));

        System.out.println(currentDateDaysAgo(DATE_STYLE_START, 15));

        String yestDay1 = "2014-11-11 15:00:00";
        java.util.Date yestDaySrc1 = DateUtils.parseDate(yestDay1, new String[] {DATE_STYLE_BASIC});
        log.info(isAfterNow(yestDaySrc1));

        System.out.println(new Date().getTime() / 1000);*/

        //        System.out.println(DateFormatUtils.format(
        //            (DateUtils.addDays(DateUtils.parseDate("2017-04-05", new String[] {"yyyy-MM-dd"}), 10)),
        //            "yyyy-MM-dd"));
        //
        //        System.out.println(DateFormatUtils.format(
        //            (DateUtils.addDays(DateUtils.parseDate("2017-03-30", new String[] {"yyyy-MM-dd"}), 10)),
        //            "yyyy-MM-dd"));
        //
        //        System.out.println(DateFormatUtils.format(
        //            (DateUtils.addDays(DateUtils.parseDate("2017-04-21", new String[] {"yyyy-MM-dd"}), 10)),
        //            "yyyy-MM-dd"));
        //
        //        System.out.println(DateFormatUtils.format(
        //            (DateUtils.addDays(DateUtils.parseDate("2017-03-27", new String[] {"yyyy-MM-dd"}), 10)),
        //            "yyyy-MM-dd"));

        //java.util.Date start = string2UtilDate("2018-11-29 22:00:00", "yyyy-MM-dd HH:mm:ss");
        //System.out.println(timeDiffIntDays(start, new java.util.Date()));

        System.out.println(firstDayOfCurrentMonth(DATE_STYLE_START));
    }

}
